<script setup lang="ts">
import * as Cesium from 'cesium'
import type { Cartesian3, Entity } from 'cesium'
import { useSatelliteStore } from '@/store/satellite'
import Orbit from '@/utils/Orbit'

type Item = {
  title: string
  value: number
}

interface SatelliteInfo {
  name: { title: string; value: string }
  Longitude: Item
  Latitude: Item
  Height: { title: string; value: string }
}

const satelliteStore = useSatelliteStore()
const color = ref<string>('rgba(255, 69, 0, 1.0)')
const orbitwidth = ref<number>(2)
const dateRange = ref<[number, number]>([Date.now(), Date.now() + 86400000])
const satelliteInfo = ref<SatelliteInfo>({
  name: { title: '名称', value: '' },
  Longitude: { title: '经度', value: 0 },
  Latitude: { title: '纬度', value: 0 },
  Height: { title: '高度', value: '' }
})
let satelliteItem: Satellite
let currentOrbitEntity: Entity | null
const orbitEntities: Entity[] = []

function showOrbit() {
  const nowOrbit = new Orbit(satelliteItem.name, satelliteItem.TLE!)
  const positions: Cartesian3[] = []
  const minutes = (dateRange.value[1] - dateRange.value[0]) / 1000 / 60
  const satrtTime = new Date(dateRange.value[0])

  for (let i = 0; i < minutes; i++) {
    const min = satrtTime.getMinutes()
    satrtTime.setMinutes(min + 1)
    const nowPosition = nowOrbit.positionGeodetic(satrtTime)
    positions.push(Cesium.Cartesian3.fromRadians(nowPosition.longitude, nowPosition.latitude, nowPosition.height * 0.1))
  }

  if (currentOrbitEntity && currentOrbitEntity.id == `orbit-${satelliteItem.name}`) {
    window.viewer.entities.remove(currentOrbitEntity)
    currentOrbitEntity = null
  }

  currentOrbitEntity = window.viewer.entities.add({
    name: satelliteItem.name,
    id: `orbit-${satelliteItem.name}`,
    polyline: {
      positions: positions,
      material: new Cesium.ColorMaterialProperty(Cesium.Color.fromCssColorString(color.value)),
      width: orbitwidth.value
    }
  })

  orbitEntities.push(currentOrbitEntity)
  color.value = getRandColor()
}

function hideOrbit() {
  const entity = window.viewer.entities.getById(`orbit-${satelliteItem.name}`)
  if (entity) window.viewer.entities.remove(entity)
}

function clearOrbit() {
  orbitEntities.forEach((entity) => window.viewer.entities.remove(entity))
}

function colorChange(color: string) {
  const entity = window.viewer.entities.getById(`orbit-${satelliteItem.name}`)
  if (entity && entity.polyline) {
    entity.polyline.material = new Cesium.ColorMaterialProperty(Cesium.Color.fromCssColorString(color))
  }
}

function widthChange(width: number | null) {
  const entity = window.viewer.entities.getById(`orbit-${satelliteItem.name}`)
  if (entity && entity.polyline) {
    entity.polyline.width = new Cesium.ConstantProperty(width)
  }
}

function getRandColor() {
  return `rgba(${(Math.random() * 255).toFixed(1)},${(Math.random() * 255).toFixed(1)}, ${(Math.random() * 255).toFixed(1)},1.0)`
}

onMounted(() => (color.value = getRandColor()))

watch(
  () => satelliteStore.satelliteInfo,
  () => {
    satelliteInfo.value.name.value = satelliteStore.satelliteInfo.name
    satelliteInfo.value.Longitude.value = parseFloat(
      Cesium.Math.toDegrees(satelliteStore.satelliteInfo.position.longitude).toFixed(3)
    )
    satelliteInfo.value.Latitude.value = parseFloat(
      Cesium.Math.toDegrees(satelliteStore.satelliteInfo.position.latitude).toFixed(3)
    )
    satelliteInfo.value.Height.value = satelliteStore.satelliteInfo.position.height.toExponential(2)
    satelliteItem = satelliteStore.satelliteInfo.satelliteItem!
  },
  { immediate: true }
)
</script>

<template>
  <div>
    <n-space vertical size="large">
      <div style="margin-bottom: 1vh">
        <n-card title="卫星信息">
          <template #header-extra>
            <n-button type="primary" quaternary>详情</n-button>
          </template>
          <n-infinite-scroll style="height: 32vh" :distance="10">
            <n-row>
              <n-col :span="12">
                <n-list hoverable class="list-panel">
                  <n-list-item>
                    <template #prefix>
                      <n-tag type="info" size="small">{{ satelliteInfo.name.title }}:</n-tag>
                    </template>
                    <n-gradient-text style="margin-left: -0.8vw" type="info">
                      {{ satelliteInfo.name.value }}
                    </n-gradient-text>
                  </n-list-item>
                  <n-list-item>
                    <template #prefix>
                      <n-tag type="info" size="small">{{ satelliteInfo.Longitude.title }}:</n-tag>
                    </template>
                    <n-gradient-text style="margin-left: -0.8vw" type="info">
                      {{ satelliteInfo.Longitude.value }}°
                    </n-gradient-text>
                  </n-list-item>
                </n-list>
              </n-col>
              <n-col :span="12">
                <n-list hoverable class="list-panel">
                  <n-list-item>
                    <template #prefix>
                      <n-tag type="info" size="small">{{ satelliteInfo.Height.title }}:</n-tag>
                    </template>
                    <n-gradient-text style="margin-left: -0.8vw" type="info">
                      {{ satelliteInfo.Height.value }}km
                    </n-gradient-text>
                  </n-list-item>
                  <n-list-item>
                    <template #prefix>
                      <n-tag type="info" size="small">{{ satelliteInfo.Latitude.title }}:</n-tag>
                    </template>
                    <n-gradient-text style="margin-left: -0.8vw" type="info">
                      {{ satelliteInfo.Latitude.value }}°
                    </n-gradient-text>
                  </n-list-item>
                </n-list>
              </n-col>
            </n-row>
            <n-flex justify="start" size="large" style="margin-top: 1vh">
              <n-tag type="info" style="margin-top: 0.6vh">轨迹线颜色:</n-tag>
              <n-color-picker
                style="width: 10vw"
                v-model:value="color"
                :on-update:value="colorChange"
                :swatches="[
                  '#FFFFFF',
                  '#18A058',
                  '#2080F0',
                  '#F0A020',
                  'rgba(208, 48, 80, 1)',
                  'rgba(255, 69, 0, 0.68)',
                  'rgb(255, 120, 0)',
                  '#c7158577'
                ]" />
            </n-flex>
            <n-flex justify="start" size="large" style="margin-top: 1vh">
              <n-tag type="info" style="margin-top: 0.6vh">轨迹线宽度:</n-tag>
              <n-input-number @update:value="widthChange" v-model:value="orbitwidth" min="1" style="width: 10vw" />
            </n-flex>
            <n-flex justify="start" size="large" style="margin-top: 1vh">
              <n-date-picker size="small" v-model:value="dateRange" type="datetimerange" clearable />
            </n-flex>
            <n-flex justify="end" size="large" style="margin-top: 2vh">
              <n-button strong secondary type="success" @click="showOrbit">显示轨迹线</n-button>
              <n-button strong secondary type="info" @click="hideOrbit">隐藏轨迹线</n-button>
              <n-button strong secondary type="info" @click="clearOrbit">清除轨迹线</n-button>
            </n-flex>
          </n-infinite-scroll>
        </n-card>
      </div>
    </n-space>
  </div>
</template>

<style lang="scss" scoped>
.n-card {
  width: 19vw;
  height: 40vh;
  background-color: transparent;
  --n-border-color: transparent;
  --n-padding-bottom: 0px;
}
.list-panel {
  width: 100%;
  background-color: transparent;
  --n-border-color: #034ba27c;
}
.tool-panel {
  display: flex;
  justify-content: flex-start;
  // align-items: center;
  flex-direction: column;
}
</style>
